package DAO;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.cassandra.thrift.*;
import org.apache.thrift.TException;
import pojo.User;

public class UserDAO {
    private static Cassandra.Client client;
    private static UserDAO instance;
    
    public static UserDAO getInstance(Cassandra.Client _client)
    {
        if (instance != null)
            return instance;
        instance = new UserDAO();
        client = _client;
        return instance;
    }
    //Lưu lại câu status ưa thích của người dùng.
    public boolean savefavoriteStatus(String UserID,String statusID)
    {
        boolean result = update(UserID,statusID,"0");
        return result;
    }
    
    //Loại câu status ra khỏi danh sách ưa thích.
    public boolean deletefavoriteStatus(String UserID, String statusID)
    {
        boolean result = update(UserID,statusID,"1");
        return result;
    }
    
    public boolean update(String UserID, String statusID,String state)
    {
        boolean result = false;
        try {
            ///Tạo supercolumn list_status_ID
            SuperColumn col = new SuperColumn();
            col.name = common.GeneralHandling.toByteBuffer(User.name_scol_favorite);
            col.addToColumns(common.GeneralHandling.createCol(statusID, state));
            
            //Insert supercolunm bằng batch_mutate
            insertSuperColumn(UserID, col);
            
            result = true;
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
    //Danh sách status ưa thích của người dùng.
    public String selectfavoriteStatus(String UserID)
    {
        String result="";
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(UserID);
            ColumnParent parent = new ColumnParent(User.col_parent);
            SlicePredicate predicate = new SlicePredicate();
            
            SliceRange range = new SliceRange();
            range.start = common.GeneralHandling.toByteBuffer("");
            range.finish = common.GeneralHandling.toByteBuffer("");
            predicate.slice_range = range;
            
            List<ColumnOrSuperColumn> listcol = client.get_slice(rowkey, parent, predicate, common.Constants.CL);
            List<ByteBuffer> liststatusID = new ArrayList<ByteBuffer>();
            for (ColumnOrSuperColumn columnOrSuperColumn : listcol) {
                SuperColumn supercol = columnOrSuperColumn.super_column;
                if (supercol.name == common.GeneralHandling.toByteBuffer(User.name_scol_favorite))
                for (Column col : supercol.columns){
                    String x = common.GeneralHandling.toString(col.value);
                    if (!x.equals("1"))
                        liststatusID.add(col.name);
                }
            }
            StatusDAO status_DAO = StatusDAO.getInstance(client);
            result = status_DAO.Getliststatus(liststatusID);
        
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            return "{}";
        } catch (TimedOutException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
    
    public boolean setBannedUser(List<String> listUser_ID, String state){
        boolean result = false;
         try {
                for (String userID : listUser_ID)
                {
                    //Tạo supercolumn info_tag
                    SuperColumn info_user = new SuperColumn();
                    info_user.name = common.GeneralHandling.toByteBuffer(User.name_scol_info);

                    info_user.addToColumns(common.GeneralHandling.createCol(User.col_banned, state));

                    //Insert supercolunm bằng batch_mutate
                    insertSuperColumn(userID, info_user);
                }
                result = true;
        
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }

    public boolean setUserName(String userID, String userName){
        boolean result = false;
         try {
                //Tạo supercolumn info_tag
                SuperColumn info_user = new SuperColumn();
                info_user.name = common.GeneralHandling.toByteBuffer(User.name_scol_info);

                info_user.addToColumns(common.GeneralHandling.createCol(User.col_userName, userName));

                //Insert supercolunm bằng batch_mutate
                insertSuperColumn(userID, info_user);
                result = true;
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
    
    public boolean isBannedUser(String userID){
        boolean result = false;
        try {
            ByteBuffer id = common.GeneralHandling.toByteBuffer(userID);
            ColumnParent parent = new ColumnParent(User.col_parent);

            ColumnPath path = new ColumnPath(User.col_parent);
            path.super_column = common.GeneralHandling.toByteBuffer(User.name_scol_info);
            ColumnOrSuperColumn user_info = client.get(id, path, common.Constants.CL);
            String is_banned = "";
            SuperColumn sCol = user_info.super_column;
            for(Column col : sCol.columns){
                if(common.GeneralHandling.toString(col.name).equals(User.col_banned)){
                    is_banned = common.GeneralHandling.toString(col.value);
                }
            }
            if("true".equals(is_banned)){
                return true;
            }else{
                return false;
            }
        }  catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotFoundException ex) {
            return true;
            //Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }   catch (UnsupportedEncodingException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return result;
    }
    
    public String ParseToJSON(SuperColumn supercol) throws UnsupportedEncodingException
    {
        List<ByteBuffer> liststatusID = new ArrayList<ByteBuffer>();
        for (Column col : supercol.getColumns()) {
            if (!"1".equals(common.GeneralHandling.toString(col.value)))
                liststatusID.add(col.name);
        }
        StatusDAO status_DAO = StatusDAO.getInstance(client);
        String result = status_DAO.Getliststatus(liststatusID);
        return result;
    }
    
    private void insertSuperColumn(String userID, SuperColumn supercol)
    {
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(userID);

            List<Mutation> mutations = new ArrayList<Mutation>();

            ColumnOrSuperColumn colorsupcol = new ColumnOrSuperColumn();
            Mutation m = new Mutation();

            colorsupcol.setSuper_column(supercol);
            m.setColumn_or_supercolumn(colorsupcol);
            mutations.add(m);

            Map<String, List<Mutation>> keyMutations = new HashMap<String, List<Mutation>>();
            keyMutations.put(User.col_parent, mutations);

            Map<ByteBuffer, Map<String, List<Mutation>>> mutationsMap = new HashMap<ByteBuffer, Map<String, List<Mutation>>>();
            mutationsMap.put(rowkey, keyMutations);
            client.batch_mutate(mutationsMap, common.Constants.CL);
            
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
